package handler

import (
	"context"
	"encoding/json"
	"errors"
	"fmt"
	"gomicro-sharemod/services/user-service/models"
	pbParams "gomicro-sharemod/services/user-service/proto/params"
	pbResult "gomicro-sharemod/services/user-service/proto/result"
	pbUser "gomicro-sharemod/services/user-service/proto/user"
	"gomicro-sharemod/services/user-service/tools"
	"math"
	"strings"
	"time"
)

/*
 +----------------------------------------------------------------------
 + Title        : UserHandler
 + Author       : huwl
 + Version      : 1.0.0
 + Initial-Time : 2019-08-08
 + Last-time    : 这个文件最后修改的时间 + 修改人的名称
 + Desc         : 用户处理
 +----------------------------------------------------------------------
*/

type UserHandler struct{}

/**
 * 新增用户
 *
 * @param string Name -----------------------非必传,姓名
 * @param string Nick -----------------------非必传,昵称
 * @param string Email ----------------------非必传,邮箱
 * @param string Username -------------------非必传,用户名
 * @param string Password -------------------非必传,密码
 * @param string AvatarUrl ------------------非必传,头像
 * @param int Source ------------------------非必传,来源
 * @param []string Hobby --------------------非必传,爱好
 * @param int Level -------------------------非必传,级别
 * @param string Mobile ---------------------非必传,手机号
 * @param int Gender ------------------------非必传,性别
 * @param int ProvinceId --------------------非必传,省ID
 * @param int CityId ------------------------非必传,市ID
 * @param int DistrictId --------------------非必传,区ID
 * @param int Score -------------------------非必传,积分
 * @param int Balance -----------------------非必传,余额
 * @param map[string]string AppendInfo ------非必传,附加信息
 * @param int Status ------------------------非必传,状态
 * @param string Token ----------------------非必传,token
 * @param string Note -----------------------非必传,备注
 * @return Code Msg error
 * @author huwl
 */
func (e *UserHandler) AddUser(ctx context.Context, req *pbUser.AddUserRequest, rsp *pbUser.AddUserResponse) error {
	password := req.Password
	username := req.Username
	mobile := req.Mobile

	if username == "" {
		return errors.New("用户名不能为空")
	}
	if !tools.CheckMobile(mobile) {
		return errors.New("请输入正确格式的手机号")
	}

	//判断用户名是否重复
	var total int64
	err := models.User{}.GetTotalByParams(&models.User{}, &total, map[string]interface{}{
		"username":    username,
		"status <> ?": -2,
	})
	if err != nil || total > 0 {
		return errors.New("用户名已存在,请重新输入")
	}

	//判断手机号是否重复
	err = models.User{}.GetTotalByParams(&models.User{}, &total, map[string]interface{}{
		"mobile":      mobile,
		"status <> ?": -2,
	})
	if err != nil || total > 0 {
		return errors.New("手机号已存在,请重新输入")
	}

	bcryptPassword := ""
	if password != "" {
		bcryptPassword, _ = tools.Bcrypt(password)
	}

	// 解析爱好
	var hobby []byte
	if len(req.Hobby) > 0 {
		hobby, _ = json.Marshal(req.Hobby)
	}

	// 解析附加信息
	var appendInfo []byte
	if len(req.AppendInfo) > 0 {
		appendInfo, _ = json.Marshal(req.AppendInfo)
	}

	user := models.User{
		Name:       req.Name,
		Nick:       req.Nick,
		Email:      req.Email,
		Username:   req.Username,
		Password:   bcryptPassword,
		AvatarUrl:  req.AvatarUrl,
		Source:     uint8(req.Source),
		Hobby:      hobby,
		Level:      uint8(req.Level),
		Mobile:     req.Mobile,
		Gender:     uint8(req.Gender),
		ProvinceId: uint16(req.ProvinceId),
		CityId:     uint16(req.CityId),
		DistrictId: uint16(req.DistrictId),
		Score:      uint16(req.Score),
		Balance:    int(req.Balance),
		AppendInfo: appendInfo,
		Status:     int8(req.Status),
		Token:      req.Token,
		Note:       req.Note,
	}
	i, err := models.User{}.Add(&user)
	if err != nil {
		return err
	}
	if i <= 0 {
		return errors.New("新增用户失败")
	}

	rsp.Code = 200
	rsp.Msg = "新增用户成功"
	rsp.User = &pbUser.User{
		Uid:        uint64(user.Uid),
		Name:       user.Name,
		Nick:       user.Nick,
		Email:      user.Email,
		Username:   user.Username,
		Password:   bcryptPassword,
		AvatarUrl:  user.AvatarUrl,
		Source:     uint32(user.Source),
		Level:      uint32(user.Level),
		Mobile:     user.Mobile,
		Gender:     uint32(user.Gender),
		ProvinceId: uint32(user.ProvinceId),
		CityId:     uint32(user.CityId),
		DistrictId: uint32(user.DistrictId),
		Score:      uint32(user.Score),
		Balance:    int64(user.Balance),
		Status:     int64(user.Status),
		Token:      user.Token,
		Note:       user.Note,
	}
	return nil
}

/**
 * 删除用户
 *
 * @param string Ids ------------------------必传,用户ID支持多个
 * @return Code Msg error
 * @author huwl
 */
func (e *UserHandler) DeleteUser(ctx context.Context, req *pbParams.IdsRequest, rsp *pbResult.Result) error {
	ids := strings.TrimRight(req.Ids, ",")

	if ids == "" {
		return errors.New("用户ID错误")
	}

	i, err := models.User{}.EditByParams(&models.User{}, map[string]interface{}{"status": -2, "update_time": time.Now()}, map[string]interface{}{
		"uid IN (?)": tools.IntSplit(ids, ","),
	})
	if err != nil {
		return err
	}
	if i <= 0 {
		return errors.New("删除用户失败")
	}

	rsp.Code = 200
	rsp.Msg = "删除用户成功"
	return nil
}

/**
 * 编辑用户
 *
 * @param int Uid ---------------------------必传,用户ID
 * @param string Name -----------------------非必传,姓名
 * @param string Nick -----------------------非必传,昵称
 * @param string Email ----------------------非必传,邮箱
 * @param string Username -------------------非必传,用户名
 * @param string Password -------------------非必传,密码
 * @param string AvatarUrl ------------------非必传,头像
 * @param int Source ------------------------非必传,来源
 * @param []string Hobby --------------------非必传,爱好
 * @param int Level -------------------------非必传,级别
 * @param string Mobile ---------------------非必传,手机号
 * @param int Gender ------------------------非必传,性别
 * @param int ProvinceId --------------------非必传,省ID
 * @param int CityId ------------------------非必传,市ID
 * @param int DistrictId --------------------非必传,区ID
 * @param int Score -------------------------非必传,积分
 * @param int Balance -----------------------非必传,余额
 * @param map[string]string AppendInfo ------非必传,附加信息
 * @param string Token ----------------------非必传,token
 * @param string Note -----------------------非必传,备注
 * @return Code Msg error
 * @author huwl
 */
func (e *UserHandler) EditUser(ctx context.Context, req *pbUser.EditUserRequest, rsp *pbResult.Result) error {
	uid := req.Uid

	if uid <= 0 {
		return errors.New("用户ID错误")
	}

	params := map[string]interface{}{"update_time": time.Now()}
	if req.Name != "" {
		params["name"] = req.Name
	}
	if req.Nick != "" {
		params["nick"] = req.Nick
	}
	if req.Email != "" {
		params["email"] = req.Email
	}
	if req.Username != "" {
		//判断用户名是否重复
		// SELECT * FROM `mall_user` where username="轮墓边狱" and status <> -2 and uid <> 2212;
		// 查询排除当前用户,其他用户名为xxx的用户，为啥要排除自己因为编辑的时候有可能提交的是自己的用户名
		// 当提交的是自己的用户名是允许的
		var total int64
		err := models.User{}.GetTotalByParams(&models.User{}, &total, map[string]interface{}{
			"username":    req.Username,
			"status <> ?": -2,
			"uid <> ?":    uid,
		})
		if err != nil || total > 0 {
			return errors.New("用户名已存在,请重新输入")
		}

		params["username"] = req.Username
	}
	if req.Password != "" {
		bcryptPassword, _ := tools.Bcrypt(req.Password)
		params["password"] = bcryptPassword
	}
	if req.AvatarUrl != "" {
		params["avatar_url"] = req.AvatarUrl
	}
	if req.Source > 0 {
		params["source"] = req.Source
	}
	if len(req.Hobby) > 0 {
		hobby, _ := json.Marshal(req.Hobby)
		params["hobby"] = hobby
	}
	if req.Level > 0 {
		params["level"] = req.Level
	}
	if req.Mobile != "" {
		//判断手机号是否重复
		// SELECT * FROM `mall_user` where mobile="轮墓边狱" and status <> -2 and uid <> 2212;
		// 查询排除当前用户,其他手机号为xxx的用户，为啥要排除自己因为编辑的时候有可能提交的是自己的手机号
		// 当提交的是自己的手机号是允许的
		var total int64
		err := models.User{}.GetTotalByParams(&models.User{}, &total, map[string]interface{}{
			"mobile":      req.Mobile,
			"status <> ?": -2,
			"uid <> ?":    uid,
		})
		if err != nil || total > 0 {
			return errors.New("手机号已存在,请重新输入")
		}
		params["mobile"] = req.Mobile
	}
	if req.Gender > 0 {
		params["gender"] = req.Gender
	}
	if req.ProvinceId > 0 {
		params["province_id"] = req.ProvinceId
	}
	if req.CityId > 0 {
		params["city_id"] = req.CityId
	}
	if req.DistrictId > 0 {
		params["district_id"] = req.DistrictId
	}
	if req.Score > 0 {
		params["score"] = req.Score
	}
	if req.Balance >= 0 {
		params["balance"] = req.Balance
	}
	if len(req.AppendInfo) > 0 {
		appendInfo, _ := json.Marshal(req.AppendInfo)
		params["append_info"] = appendInfo
	}
	if req.Token != "" {
		params["token"] = req.Token
	}
	if req.Note != "" {
		params["note"] = req.Note
	}

	i, err := models.User{}.EditByPrimaryKey(&models.User{}, params, uid, "uid")
	if err != nil {
		return err
	}
	if i <= 0 {
		return errors.New("编辑用户失败")
	}

	rsp.Code = 200
	rsp.Msg = "编辑用户成功"
	return nil
}

/**
 * 编辑用户状态
 *
 * @param string Ids ------------------------必传,用户ID支持多个
 * @param int Status ------------------------必传,状态
 * @return Code Msg error
 * @author huwl
 */
func (e *UserHandler) EditUserStatus(ctx context.Context, req *pbParams.EditStatusRequest, rsp *pbResult.Result) error {
	uids := strings.TrimRight(req.Ids, ",")
	status := req.Status

	if uids == "" {
		return errors.New("用户ID错误")
	}
	if status == 0 {
		return errors.New("用户状态错误")
	}

	result, err := models.User{}.EditByParams(&models.User{}, map[string]interface{}{"status": status, "update_time": time.Now()}, map[string]interface{}{
		"uid IN (?)": tools.IntSplit(uids, ","),
	})
	if err != nil {
		return err
	}

	message := ""
	if status == 1 {
		message = "启用用户"
	} else {
		message = "禁用用户"
	}
	if result <= 0 {
		return errors.New(message + "失败")
	}

	rsp.Code = 200
	rsp.Msg = message + "成功"
	return nil
}

/**
 * 用户详情
 *
 * @param int Uid ---------------------------必传,用户ID
 * @return User error
 * @author huwl
 */
func (e *UserHandler) UserDetail(ctx context.Context, req *pbUser.UserDetailRequest, rsp *pbUser.UserResponse) error {
	uid := req.Uid
	isHaveUserAlbum := req.IsHaveUserAlbum
	if uid <= 0 {
		return errors.New("用户ID错误")
	}

	user := models.User{}
	i, err := models.User{}.GetResultByPrimaryKey(&user, uid, "uid")
	if err != nil {
		return err
	}
	if i <= 0 || user.Status == -2 {
		return errors.New("用户信息错误")
	}

	//获取用户相册
	userAlbums := []*pbUser.UserAlbum{}
	if isHaveUserAlbum == 1 {
		userAlbumItems := []models.UserAlbum{}
		err := models.UserAlbum{}.GetResultsByParams(&models.UserAlbum{}, &userAlbumItems, map[string]interface{}{
			"uid": uid,
		}, 1, -1, "id asc")
		if err != nil {
			return err
		}

		for _, userAlbumItem := range userAlbumItems {
			userAlbums = append(userAlbums, &pbUser.UserAlbum{
				Id:          int64(userAlbumItem.Id),
				Uid:         int64(userAlbumItem.Uid),
				ImageUrl:    userAlbumItem.ImageUrl,
				Description: userAlbumItem.Description,
				CreateTime:  userAlbumItem.CreateTime.Format("2006-01-02 15:04:05"),
				UpdateTime:  userAlbumItem.UpdateTime.Format("2006-01-02 15:04:05"),
			})
		}
	}

	// 解析json数据
	var hobby []string
	json.Unmarshal(user.Hobby, &hobby)
	var appendInfo map[string]string
	json.Unmarshal(user.AppendInfo, &appendInfo)

	rsp.User = &pbUser.User{
		Uid:        uint64(user.Uid),
		Name:       user.Name,
		Nick:       user.Nick,
		Email:      user.Email,
		Username:   user.Username,
		Password:   user.Password,
		AvatarUrl:  user.AvatarUrl,
		Source:     uint32(user.Source),
		Hobby:      hobby,
		Level:      uint32(user.Level),
		Mobile:     user.Mobile,
		Gender:     uint32(user.Gender),
		ProvinceId: uint32(user.ProvinceId),
		CityId:     uint32(user.CityId),
		DistrictId: uint32(user.DistrictId),
		Score:      uint32(user.Score),
		Balance:    int64(user.Balance),
		AppendInfo: appendInfo,
		Status:     int64(user.Status),
		Token:      user.Token,
		Note:       user.Note,
		CreateTime: user.CreateTime.Format("2006-01-02 15:04:05"),
		UpdateTime: user.UpdateTime.Format("2006-01-02 15:04:05"),
	}

	rsp.UserAlbums = userAlbums
	return nil
}

/**
 * 用户列表
 *
 * @param int Uid ---------------------------非必传,用户Id
 * @param string Uids -----------------------非必传,用户Id支持多个
 * @param string Name -----------------------非必传,姓名
 * @param string Nick -----------------------非必传,昵称
 * @param string Username -------------------非必传,用户名
 * @param string Email ----------------------非必传,邮箱
 * @param int Source ------------------------非必传,来源
 * @param []string Hobby --------------------非必传,爱好
 * @param int Level -------------------------非必传,级别
 * @param string Mobile ---------------------非必传,手机号
 * @param int Gender ------------------------非必传,性别
 * @param int ProvinceId --------------------非必传,省Id
 * @param int CityId ------------------------非必传,城市Id
 * @param int DistrictId --------------------非必传,区Id
 * @param map[string]string AppendInfo ------非必传,附加信息
 * @param string Status ---------------------非必传,状态支持多个：1,-1
 * @param string StartCreateTime ------------非必传,开始创建时间
 * @param string EndCreateTime --------------非必传,结束创建时间
 * @param string SortField ------------------非必传,排序字段
 * @param string SortType -------------------非必传,排序方式
 * @param int PageSize ----------------------非必传,条数
 * @param int Page --------------------------非必传,页码
 * @return Code Page Total PageSize PageTotal Users error
 * @author huwl
 */
func (e *UserHandler) UserList(ctx context.Context, req *pbUser.QueryUserRequest, rsp *pbUser.UserListResponse) error {
	params := map[string]interface{}{
		"status <> ?": -2,
	}

	page := req.Page
	pageSize := req.PageSize
	sortType := req.SortType
	sortField := req.SortField

	if req.Uid > 0 {
		params["uid"] = req.Uid
	}
	if req.Uids != "" {
		params["uid IN (?)"] = tools.IntSplit(strings.TrimRight(req.Uids, ","), ",")
	}
	if req.Name != "" {
		params["name"] = req.Name
	}
	if req.Nick != "" {
		params["nick"] = req.Nick
	}
	if req.Email != "" {
		params["email"] = req.Email
	}
	if req.Username != "" {
		params["username"] = req.Username
	}
	if req.Source > 0 {
		params["source"] = req.Source
	}
	if req.Hobby != "" {
		// 查询: ["吃饭", "睡觉", "撸猫"]
		// SELECT * FROM tour_demo WHERE JSON_CONTAINS(hobby, '["吃饭"]')
		params["JSON_CONTAINS(hobby, ?)"] = fmt.Sprintf(`["%s"]`, req.Hobby)
	}
	if req.Level > 0 {
		params["level"] = req.Level
	}
	if req.Mobile != "" {
		params["mobile"] = req.Mobile
	}
	if req.Gender > 0 {
		params["gender"] = req.Gender
	}
	if req.ProvinceId > 0 {
		params["province_id"] = req.ProvinceId
	}
	if req.CityId > 0 {
		params["city_id"] = req.CityId
	}
	if req.DistrictId > 0 {
		params["district_id"] = req.DistrictId
	}
	if req.AppendInfo != "" {
		// 查询: {"job": "司机", "label": "xxxx"}
		// 使用 ->> 操作符 (MySQL 5.7.13+)
		// Where("JSON_EXTRACT(append_info, '$.job') = ?", "司机")
		params["JSON_EXTRACT(append_info, '$.job') = ?"] = req.AppendInfo
	}
	if req.Status != "all" {
		params["status in (?)"] = tools.IntSplit(req.Status, ",")
	}
	if req.StartCreateTime != "" {
		params["create_time >= ?"] = req.StartCreateTime + " 00:00:00"
	}
	if req.EndCreateTime != "" {
		params["create_time <= ?"] = req.EndCreateTime + " 23:59:59"
	}
	if page <= 0 {
		page = 1
	}
	if pageSize == 0 {
		pageSize = 20
	}
	if sortField == "" {
		sortField = "uid"
	}
	if sortType == "" {
		sortType = "desc"
	}

	var total int64
	err := models.User{}.GetTotalByParams(&models.User{}, &total, params)
	if err != nil {
		return err
	}

	users := []*pbUser.User{}
	userItems := []models.User{}
	if total > 0 {
		err := models.User{}.GetResultsByParams(&models.User{}, &userItems, params, int(page), int(pageSize), sortField+" "+sortType)
		if err != nil {
			return err
		}

		for _, user := range userItems {
			// 解析json数据
			var hobby []string
			json.Unmarshal(user.Hobby, &hobby)
			var appendInfo map[string]string
			json.Unmarshal(user.AppendInfo, &appendInfo)

			users = append(users, &pbUser.User{
				Uid:        uint64(user.Uid),
				Name:       user.Name,
				Nick:       user.Nick,
				Email:      user.Email,
				Username:   user.Username,
				Password:   user.Password,
				AvatarUrl:  user.AvatarUrl,
				Source:     uint32(user.Source),
				Level:      uint32(user.Level),
				Mobile:     user.Mobile,
				Gender:     uint32(user.Gender),
				ProvinceId: uint32(user.ProvinceId),
				CityId:     uint32(user.CityId),
				DistrictId: uint32(user.DistrictId),
				Score:      uint32(user.Score),
				Balance:    int64(user.Balance),
				Status:     int64(user.Status),
				Token:      user.Token,
				Note:       user.Note,
				CreateTime: user.CreateTime.Format("2006-01-02 15:04:05"),
				UpdateTime: user.UpdateTime.Format("2006-01-02 15:04:05"),
			})
		}
	}

	pageTotal := math.Ceil(float64(total) / float64(pageSize))

	rsp.ListResult = &pbResult.ListCommonResult{
		Page:      page,
		Total:     uint32(total),
		PageSize:  pageSize,
		PageTotal: int32(pageTotal),
	}
	rsp.Users = users
	return nil
}

/**
 * 用户数量
 *
 * @param int uid ---------------------------非必传,用户Id
 * @param string uids -----------------------非必传,用户Id支持多个
 * @param string Name -----------------------非必传,姓名
 * @param string Nick -----------------------非必传,昵称
 * @param string Username -------------------非必传,用户名
 * @param int Source ------------------------非必传,来源
 * @param []string Hobby --------------------非必传,爱好
 * @param int Level -------------------------非必传,级别
 * @param string Mobile ---------------------非必传,手机号
 * @param int Gender ------------------------非必传,性别
 * @param int ProvinceId --------------------非必传,省Id
 * @param int CityId ------------------------非必传,城市Id
 * @param int DistrictId --------------------非必传,区Id
 * @param map[string]string AppendInfo ------非必传,附加信息
 * @param string Status ---------------------非必传,状态支持多个：1,-1
 * @param string StartCreateTime ------------非必传,开始创建时间
 * @param string EndCreateTime --------------非必传,结束创建时间
 * @return Total error
 * @author huwl
 */
func (e *UserHandler) UserTotal(ctx context.Context, req *pbUser.QueryUserRequest, rsp *pbResult.TotalResult) error {
	params := map[string]interface{}{
		"status <> ?": -2,
	}

	page := req.Page
	pageSize := req.PageSize
	sortType := req.SortType
	sortField := req.SortField

	if req.Uid > 0 {
		params["uid"] = req.Uid
	}
	if req.Uids != "" {
		params["uid IN (?)"] = tools.IntSplit(strings.TrimRight(req.Uids, ","), ",")
	}
	if req.Name != "" {
		params["name"] = req.Name
	}
	if req.Nick != "" {
		params["nick"] = req.Nick
	}
	if req.Email != "" {
		params["email"] = req.Email
	}
	if req.Username != "" {
		params["username"] = req.Username
	}
	if req.Source > 0 {
		params["source"] = req.Source
	}
	if req.Hobby != "" {
		// 查询: ["吃饭", "睡觉", "撸猫"]
		// SELECT * FROM tour_demo WHERE JSON_CONTAINS(hobby, '["吃饭"]')
		params["JSON_CONTAINS(hobby, ?)"] = fmt.Sprintf(`["%s"]`, req.Hobby)
	}
	if req.Level > 0 {
		params["level"] = req.Level
	}
	if req.Mobile != "" {
		params["mobile"] = req.Mobile
	}
	if req.Gender > 0 {
		params["gender"] = req.Gender
	}
	if req.ProvinceId > 0 {
		params["province_id"] = req.ProvinceId
	}
	if req.CityId > 0 {
		params["city_id"] = req.CityId
	}
	if req.DistrictId > 0 {
		params["district_id"] = req.DistrictId
	}
	if req.AppendInfo != "" {
		// 查询: {"job": "司机", "label": "xxxx"}
		// 使用 ->> 操作符 (MySQL 5.7.13+)
		// Where("JSON_EXTRACT(append_info, '$.job') = ?", "司机")
		params["JSON_EXTRACT(append_info, '$.job') = ?"] = req.AppendInfo
	}
	if req.Status != "all" {
		params["status in (?)"] = tools.IntSplit(req.Status, ",")
	}
	if req.StartCreateTime != "" {
		params["create_time >= ?"] = req.StartCreateTime + " 00:00:00"
	}
	if req.EndCreateTime != "" {
		params["create_time <= ?"] = req.EndCreateTime + " 23:59:59"
	}
	if page <= 0 {
		page = 1
	}
	if pageSize == 0 {
		pageSize = 20
	}
	if sortType == "" {
		sortType = "id"
	}
	if sortField == "" {
		sortType = "desc"
	}

	var total int64
	err := models.User{}.GetTotalByParams(&models.User{}, &total, params)
	if err != nil {
		return err
	}
	rsp.Total = uint32(total)
	return nil
}

/**
 * 获取单条用户信息
 *
 * @param string Name -----------------------------------非必传,姓名
 * @param string Nick -----------------------------------非必传,昵称
 * @param string Username -------------------------------非必传,用户名
 * @param int Source ------------------------------------非必传,来源
 * @param int Level -------------------------------------非必传,级别
 * @param string Mobile ---------------------------------非必传,手机号
 * @param int Gender ------------------------------------非必传,性别
 * @param int ProvinceId --------------------------------非必传,省ID
 * @param int CityId ------------------------------------非必传,城市ID
 * @param int DistrictId --------------------------------非必传,区ID
 * @param string Status ---------------------------------非必传,状态支持多个：1,-1
 * @return User error
 * @author huwl
 */
func (e *UserHandler) Row(ctx context.Context, req *pbUser.QueryUserRequest, rsp *pbUser.UserResponse) error {
	params := map[string]interface{}{
		"status <> ?": -2,
	}

	if req.Name != "" {
		params["name"] = req.Name
	}
	if req.Nick != "" {
		params["nick"] = req.Nick
	}
	if req.Email != "" {
		params["email"] = req.Email
	}
	if req.Username != "" {
		params["username"] = req.Username
	}
	if req.Source > 0 {
		params["source"] = req.Source
	}
	if req.Level > 0 {
		params["level"] = req.Level
	}
	if req.Mobile != "" {
		params["mobile"] = req.Mobile
	}
	if req.Gender > 0 {
		params["gender"] = req.Gender
	}
	if req.ProvinceId > 0 {
		params["province_id"] = req.ProvinceId
	}
	if req.CityId > 0 {
		params["city_id"] = req.CityId
	}
	if req.DistrictId > 0 {
		params["district_id"] = req.DistrictId
	}
	if req.Status != "all" {
		params["status in (?)"] = tools.IntSplit(req.Status, ",")
	}

	user := models.User{}
	i, err := models.User{}.Row(&models.User{}, &user, params)
	if err != nil {
		return err
	}
	if i <= 0 {
		return errors.New("用户信息错误")
	}

	// 解析json数据
	var hobby []string
	json.Unmarshal(user.Hobby, &hobby)
	var appendInfo map[string]string
	json.Unmarshal(user.AppendInfo, &appendInfo)

	rsp.User = &pbUser.User{
		Uid:        uint64(user.Uid),
		Name:       user.Name,
		Nick:       user.Nick,
		Email:      user.Email,
		Username:   user.Username,
		Password:   user.Password,
		AvatarUrl:  user.AvatarUrl,
		Source:     uint32(user.Source),
		Hobby:      hobby,
		Level:      uint32(user.Level),
		Mobile:     user.Mobile,
		Gender:     uint32(user.Gender),
		ProvinceId: uint32(user.ProvinceId),
		CityId:     uint32(user.CityId),
		DistrictId: uint32(user.DistrictId),
		Score:      uint32(user.Score),
		Balance:    int64(user.Balance),
		AppendInfo: appendInfo,
		Status:     int64(user.Status),
		Token:      user.Token,
		Note:       user.Note,
		CreateTime: user.CreateTime.Format("2006-01-02 15:04:05"),
		UpdateTime: user.UpdateTime.Format("2006-01-02 15:04:05"),
	}
	return nil
}

/**
 * 多个用户ID获取用户信息
 *
 * @param string Ids ------------------------必传,用户ID支持多个
 * @return Users error
 * @author huwl
 */
func (e *UserHandler) Rows(ctx context.Context, req *pbParams.IdsRequest, rsp *pbUser.UserListResponse) error {
	ids := strings.TrimRight(req.Ids, ",")

	if ids == "" {
		return errors.New("用户ID错误")
	}

	uids := tools.IntSplit(ids, ",")
	userIds := []interface{}{}
	for _, uid := range uids {
		userIds = append(userIds, uid)
	}

	userItems := []models.User{}
	err := models.User{}.Rows(&userItems, userIds)
	if err != nil {
		return err
	}

	users := []*pbUser.User{}
	for _, user := range userItems {
		// 解析json数据
		var hobby []string
		json.Unmarshal(user.Hobby, &hobby)
		var appendInfo map[string]string
		json.Unmarshal(user.AppendInfo, &appendInfo)

		users = append(users, &pbUser.User{
			Uid:        uint64(user.Uid),
			Name:       user.Name,
			Nick:       user.Nick,
			Email:      user.Email,
			Username:   user.Username,
			Password:   user.Password,
			AvatarUrl:  user.AvatarUrl,
			Source:     uint32(user.Source),
			Hobby:      hobby,
			Level:      uint32(user.Level),
			Mobile:     user.Mobile,
			Gender:     uint32(user.Gender),
			ProvinceId: uint32(user.ProvinceId),
			CityId:     uint32(user.CityId),
			DistrictId: uint32(user.DistrictId),
			Score:      uint32(user.Score),
			Balance:    int64(user.Balance),
			AppendInfo: appendInfo,
			Status:     int64(user.Status),
			Token:      user.Token,
			Note:       user.Note,
			CreateTime: user.CreateTime.Format("2006-01-02 15:04:05"),
			UpdateTime: user.UpdateTime.Format("2006-01-02 15:04:05"),
		})
	}

	rsp.Users = users
	return nil
}

/**
 * 新增用户相册
 *
 * @param int Uid ---------------------------------------必传,用户ID
 * @param []*pbUser.UserAlbumParams UserAlbumParams -----必传,相册参数
 * @return Code Msg error
 * @author huwl
 */
func (e *UserHandler) AddUserAlbum(ctx context.Context, req *pbUser.AddUserAlbumRequest, rsp *pbResult.Result) error {
	uid := req.Uid
	userAlbumParams := req.UserAlbumParams

	if uid <= 0 {
		return errors.New("用户ID不能为空")
	}
	if len(userAlbumParams) <= 0 {
		return errors.New("图片地址不能为空")
	}

	params := []models.UserAlbum{}
	for _, userAlbumParam := range userAlbumParams {
		if userAlbumParam.ImageUrl == "" {
			return errors.New("图片地址不能为空")
		}
		params = append(params, models.UserAlbum{
			Uid:         int(uid),
			ImageUrl:    userAlbumParam.ImageUrl,
			Description: userAlbumParam.Description,
		})
	}

	result, err := models.UserAlbum{}.Add(&params)
	if err != nil {
		return err
	}
	if result <= 0 {
		return errors.New("新增用户相册失败")
	}

	rsp.Code = 200
	rsp.Msg = "新增相册成功"
	return nil
}

/**
 * 获取用户相册
 *
 * @param int Uid ---------------------------------------非必传,用户ID
 * @param string SortType -------------------------------非必传,排序方式
 * @param string SortField ------------------------------非必传,排序字段
 * @param string PageSize -------------------------------非必传,条数
 * @param string Page -----------------------------------非必传,页码
 * @return UserAlbums error
 * @author huwl
 */
func (e *UserHandler) GetUserAlbum(ctx context.Context, req *pbUser.GetUserAlbumRequest, rsp *pbUser.UserAlbumResponse) error {
	params := map[string]interface{}{}
	if req.Uid > 0 {
		params["uid"] = req.Uid
	}

	page := req.Page
	pageSize := req.PageSize
	sortType := req.SortType
	sortField := req.SortField

	if page <= 0 {
		page = 1
	}
	if pageSize == 0 {
		pageSize = 20
	}
	if sortType == "" {
		sortType = "id"
	}
	if sortField == "" {
		sortType = "desc"
	}

	userAlbumItems := []models.UserAlbum{}
	err := models.UserAlbum{}.GetResultsByParams(&models.UserAlbum{}, &userAlbumItems, params, int(page), int(pageSize), sortField+" "+sortType)
	if err != nil {
		return err
	}

	userAlbums := []*pbUser.UserAlbum{}
	for _, userAlbumItem := range userAlbumItems {
		userAlbums = append(userAlbums, &pbUser.UserAlbum{
			Id:          int64(userAlbumItem.Id),
			ImageUrl:    userAlbumItem.ImageUrl,
			Description: userAlbumItem.Description,
			CreateTime:  userAlbumItem.CreateTime.Format("2006-01-02 15:04:05"),
			UpdateTime:  userAlbumItem.UpdateTime.Format("2006-01-02 15:04:05"),
		})
	}

	rsp.UserAlbums = userAlbums
	return nil
}

/**
 * 修改密码
 *
 * @param string raw_password ---------------必传,原密码
 * @param string new_password ---------------必传,新密码
 * @param string repassword -----------------必传,确认密码
 * @return error rsp.Msg rsp.Code
 * @author huwl
 */
func (e *UserHandler) ChangePassword(ctx context.Context, req *pbUser.ChangePasswordRequest, rsp *pbResult.Result) error {
	if req.Uid <= 0 {
		return errors.New("用户ID错误")
	}
	if req.RawPassword == "" {
		return errors.New("原密码不能为空")
	}
	if req.NewPassword == "" {
		return errors.New("新密码不能为空")
	}

	// 获取用户信息
	user := models.User{}
	i, err := models.User{}.GetResultByPrimaryKey(&user, req.Uid, "uid")
	if err != nil {
		return err
	}
	if i <= 0 || user.Status == -2 {
		return errors.New("用户信息错误")
	}

	// 判断用户原密码
	if !tools.CompareBcrypt(user.Password, req.RawPassword) {
		return errors.New("原密码错误")
	}

	// 修改密码
	bcryptPassword, _ := tools.Bcrypt(req.NewPassword)
	i, err = models.User{}.EditByPrimaryKey(&models.User{}, map[string]interface{}{
		"password": bcryptPassword,
	}, req.Uid, "uid")
	if err != nil {
		return err
	}
	if i <= 0 {
		return errors.New("修改密码失败")
	}

	rsp.Code = 200
	rsp.Msg = "修改密码成功"
	return nil
}
